/* Bump mapping functions
 *
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include "bump.h"
#include "hw5.h"

int draw_polyline () {

	int i;
	float dx;

	dx = 62.5;

	glColor3f ( 0., 1., 0. );

	for ( i = 0; i < SEGMENTS; i++ ) {

		glBegin ( GL_LINES );
			glVertex2i ( i * dx + 50,
				polyline [ i ] + PVIEWH / 2 );
			glVertex2i ( ( i + 1 ) * dx + 50,
				polyline [ i + 1 ] + PVIEWH / 2 );
		glEnd ();
	}

	glPointSize ( 5 );

	glBegin ( GL_POINTS );

		for ( i = 0; i < MAX_POINTS; i++ ) {

			glVertex2i ( i * dx + 50,
				polyline [ i ] + PVIEWH / 2 );
		}

	glEnd ();

	return 0;
}

int draw_normals ( ) {

	int i;
	int magnitude = 25;

	float dx = 62.5;	
	glColor3f ( 0., 0., 1. );

	for ( i = 0; i < SEGMENTS; i++ ) {

		glBegin ( GL_LINES );
			glVertex2i ( ( i + .5 ) * dx + 50, 
				( polyline [ i ] + polyline [ i + 1 ] ) / 2 + PVIEWH / 2 );
			glVertex2i ( ( i + .5 ) * dx + normal [ i ][ X ] * magnitude + 50,
				( polyline [ i ] + polyline [ i + 1 ] ) / 2 + normal [ i ][ Y ] * magnitude + PVIEWH / 2 );
		glEnd ();		
	}

	return 0;
}

int calculate_normals ( int v ) {

	int dx;
	float *p1, *p2, *n;

	p1 = ( float * ) malloc ( 3 * sizeof ( float ) );
	p2 = ( float * ) malloc ( 3 * sizeof ( float ) );
	n = ( float * ) malloc ( 3 * sizeof ( float ) );

	dx = ( WIDTH - 100 ) / ( SEGMENTS - 1 );

	p1 [ X ] = v * dx;
	p1 [ Y ] = polyline [ v ];
	p1 [ Z ] = 0;

	/* do right segment normal */
	if ( v < MAX_POINTS - 1 ) { 

		p2 [ X ] = ( v + 1 ) * dx;
		p2 [ Y ] = polyline [ v + 1 ];
		p2 [ Z ] = 0;

		find_unitVec ( p1, p2, n );
		normal [ v ][ X ] = -n [ Y ];
		normal [ v ][ Y ] = n [ X ];
	}

	/* do left segment normal */
	if ( v > 0 ) {

		p2 [ X ] = ( v - 1 ) * dx;
		p2 [ Y ] = polyline [ v - 1 ];
		p2 [ Z ] = 0;

		find_unitVec ( p2, p1, n );
		normal [ v - 1 ][ X ] = -n [ Y ];
		normal [ v - 1 ][ Y ] = n [ X ];
	}

	free ( p1 ); free ( p2 ); free ( n );

	return 0;
}

/* This function takes the normal values in the polyline and alters the
 * texture to be shaded according to those normal values. */
void normalize_texture(ByteRaster* imgold, ByteRaster* imgnew){
	int i,j;
	int segno, cnt, segamt;
	float dot_result;
	
	segamt = imgold->width()/(SEGMENTS);
	// loop through the pixel data of imgold and modify it according to
	// the normals and copy the modified pixel to imgnew
	for(j=0; j< imgold->height(); j++){
		segno = 0;
		cnt=0;							// start in the first segment of the polyline
		dot_result = 0.0*normal[segno][X]+0.0*0.0+1.0*normal[segno][Y];

		for(i=0; i< imgold->width(); i++){
			if(cnt>segamt){
				segno++;
				cnt=0;
				dot_result = 0.0*normal[segno][X]+0.0*0.0+1.0*normal[segno][Y];
			}
			cnt++;
			imgnew->pixel(i,j)[RED] = imgold->pixel(i,j)[RED]*dot_result;
			imgnew->pixel(i,j)[BLUE] = imgold->pixel(i,j)[BLUE]*dot_result;
			imgnew->pixel(i,j)[GREEN] = imgold->pixel(i,j)[GREEN]*dot_result;
		}
	}
	
}
